
namespace Patterns4Net.Tests.Core.Conventions
{
    using System;
    using System.Linq;
    using Mono.Cecil;
    using NUnit.Framework;
    using Patterns4Net.Core;
    using Patterns4Net.Core.AttributesPatterns;
    using Patterns4Net.Core.CecilExtensions;
    using Patterns4Net.Core.Patterns;
    using Patterns4Net.Attributes;

    [TestFixture]
    public class AttributesPatternsProviderTest
    {
        private static readonly IPattern Pattern = new Moq.Mock<IPattern>().Object;

        [Test]
        public void GetPatterns_Of_Class_Decorated_PatternAttribute_Returns_Correct_Pattern_Instance()
        {
            var creator = new Moq.Mock<ICreatePatternFromAttribute>();
            creator.Setup(x =>
                x.Crate(
                    Moq.It.Is<CustomAttribute>(attr => attr.AttributeType.Name == "PatternAttribute"),
                    Moq.It.Is<IMemberDefinition>(member => member.Name == "DecoratedClass")))
                .Returns(Pattern)
                .Verifiable();
            var creatorAndMetadata =
                new Lazy<ICreatePatternFromAttribute, PatternCreatorExportAttribute>(
                    () => creator.Object, 
                    new PatternCreatorExportAttribute(typeof(PatternAttribute)));

            var provider = new PlainAttributesPatternsProvider(new[] { creatorAndMetadata });
            var result = provider.GetPatterns(typeof(DecoratedClass).GetTypeDefinition());

            CollectionAssert.IsNotEmpty(result);
            Assert.AreSame(Pattern, result.First());
        }

        [Pattern]
        public class DecoratedClass
        {    
        }

        public class PatternAttribute : Attribute, IPatternAttribute
        {
        }
    }
}
